using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Linq;

namespace PokerStar.Core
{
    public class Game
    {
        private readonly int _maxPlayers;
        private readonly TexasHoldem _algo;
        private Dealer _dealer;
        private IList<Player> _players;
        private Pot _pot;
        private ITurn _flop;
        private ITurn _turn;
        private ITurn _river;

        private StringBuilder _buffer;

        public Game(int maxPlayers)
        {
            _maxPlayers = maxPlayers;
            _players = new List<Player>();
            _dealer = new Dealer();
            _algo = new TexasHoldem();
        }

        public void AddPlayer(Player player)
        {
            _players.Add(player);
        }

        public void Play()
        {
            foreach (var player in _players)
            {
                player.Reset();
            }
            _buffer = new StringBuilder();

            _buffer.AppendLine("Game started.");

            // players
            foreach (var player in _players)
            {
                _buffer.AppendLine(player.ToString());
            }

            // button move
            _dealer.ButtonMove(_players[0]);
            _buffer.AppendLine("Button moved to " + _players[0]);

            // shuffle
            _dealer.Shuffle();
            _buffer.AppendLine("Shuffle cards.");
            _buffer.AppendLine(_dealer.PrintCards());
            //_buffer.AppendLine();

            // give cards
            _buffer.AppendLine("Give card.");
            for (int i = 0; i < 2; i++)
            {
                foreach (var player in _players)
                {
                    var card = _dealer.GiveCard(player);
                    //_buffer.AppendFormat(" -> {0}: {1}\r\n", player, card);
                }
            }
            foreach (var player in _players)
            {
                _buffer.AppendLine(player.ToString());
            }

            // flop
            _buffer.Append("Flop -> ");
            var flop = _dealer.PlayFlop();
            foreach (var card in flop)
            {
                _buffer.Append(card);
                _buffer.Append(' ');
            }
            _buffer.AppendLine();

            // turn
            _buffer.Append("Turn -> ");
            var turn = _dealer.PlayTurn();
            _buffer.AppendLine(turn.ToString());

            // river
            _buffer.Append("River -> ");
            var river = _dealer.PlayRiver();
            _buffer.AppendLine(river.ToString());

            // winner
            //_algo.Reset(flop, turn, river);
            foreach (var player in _players)
            {
                player.Result = _algo.Calculate(player.Cards, flop, turn, river);
                //_buffer.AppendLine(player + player.Result.ToString());
            }
            //var sortedPlayers = _players.OrderBy(p => p.Result);
            //_buffer.Append("Winner is " + sortedPlayers.First());

            _buffer.AppendLine("Winner: ");
            var rc = new GameResultCollection(_players);
            int index = 0;
            foreach (var rate in rc.GetRates())
            {
                index++;
                foreach (var player in rate)
                {
                    _buffer.AppendFormat(" {0} {1} -> {2}\r\n", index, player, player.Result);
                }
            }

            _buffer.AppendLine("Game over.");
        }

        public string GetStatistics()
        {
            return _buffer.ToString();
        }
    }
}